package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.AuthorTypeConstants;
import com.hbnu.system.mapper.PatentauthorMapper;
import com.hbnu.system.model.entity.Patent;
import com.hbnu.system.model.entity.Patentauthor;
import com.hbnu.system.model.entity.Porprojectauthor;
import com.hbnu.system.model.entity.User;
import com.hbnu.system.service.IPatentQualificationSerivce;
import com.hbnu.system.service.IPatentService;
import com.hbnu.system.service.IPatentauthorService;
import com.hbnu.system.service.IUserService;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.IdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-05-16
 */
@Service
public class PatentauthorServiceImpl extends ServiceImpl<PatentauthorMapper, Patentauthor> implements IPatentauthorService {

    @Autowired
    private IPatentauthorService iPatentauthorService;

    @Autowired
    private IPatentService iPatentService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private CheckRoleUtil checkRoleUtil;

    @Autowired
    private IPatentQualificationSerivce iPatentQualificationSerivce;

    private static final List<String> AUTHOR_TYPE_ORDER = Arrays.asList(
            "第一发明人", "共同第一发明人", "通讯发明人", "第二发明人", "第三发明人", "其他排名"
    );

    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00");

    /**
     * 添加专利作者
     * @param patentAuthor
     * @return
     */
    @Override
    public boolean addPatentAuthor(Patentauthor patentAuthor) {
        // 不使用前端传过来的id，而是生成一个新的id
        patentAuthor.setPatentAuthorID(null);
        Patent p = iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();
        checkRoleUtil.checkPermissionAchievement(p.getStatus());

        //如果是校外作者或者学生，为其生成工号
        if (AuthorTypeConstants.OUT_SCHOOL_AUTHOR.equals(patentAuthor.getPeopleType())
                || AuthorTypeConstants.STUDENT.equals(patentAuthor.getPeopleType())) {
            patentAuthor.setUserAccount(IdGenerator.generateId());
        }

        if (StrUtil.isEmpty(patentAuthor.getUserAccount())) {
            throw new BaseException("请输入工号");
        }

        Patentauthor pa1 = iPatentauthorService.getOne(Wrappers.lambdaQuery(Patentauthor.class)
                .eq(Patentauthor::getPatentID, patentAuthor.getPatentID())
                .eq(Patentauthor::getUserAccount, patentAuthor.getUserAccount()));
        if (Objects.nonNull(pa1)) {
            throw new BaseException("不可重复添加");
        }
        if (StrUtil.isEmpty(patentAuthor.getAssessment())) {
            throw new BaseException("请输入考核系数");
        }

        double newAssessment;
        try {
            newAssessment = Double.parseDouble(patentAuthor.getAssessment());
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0-100范围内");
        }

        String Pscore = "0.00";

        Patent patent= iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();

        if(patent != null){
            float finalValue = patent.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 判断加起来总分是否超过100
        List<Patentauthor> patentauthorList = iPatentauthorService.listAuthor(patentAuthor.getPatentID());
        double sum = 0;
        for (Patentauthor patentauthor : patentauthorList) {
            if(StrUtil.isEmpty(patentauthor.getAssessment())){
                throw new BaseException("请补全所有作者考核系数");
            }
            sum += Double.parseDouble(patentauthor.getAssessment());
        }
        if (sum + newAssessment > 100) {
            throw new BaseException("作者考核系数总和大于100!");
        }

        // 如果新增的作者是第一作者的话，要判断是否已经有第一作者
        if ("第一发明人".equals(patentAuthor.getAuthortype())) {
            for (Patentauthor patentauthor : patentauthorList) {
                if ("第一发明人".equals(patentauthor.getAuthortype())) {
                    throw new BaseException("该专利已存在第一发明人!");
                }
            }
        }
        save(patentAuthor);

        patentAuthor.setPscore(Pscore);
        // 维护AllInventor字段
        updateAllInventor(p, patentAuthor);

        return true;
    }

    /**
     * 删除专利作者
     * @param id
     * @return
     */
    @Override
    public boolean deletePatentAuthor(String id) {
        Patentauthor patentauthor = super.getOne(Wrappers.lambdaQuery(Patentauthor.class)
                .eq(Patentauthor::getPatentAuthorID, id));
        // 拦截普通用户在非法状态删除
        Patent p = iPatentService.query().eq("PatentID", patentauthor.getPatentID()).one();
        checkRoleUtil.checkPermissionAchievement(p.getStatus());

        boolean result = baseMapper.deleteById(patentauthor) == 1;

        // 维护AllInventor字段
        if (result) {
            updateAllInventor(p, patentauthor);
        }

        return result;
    }

    /**
     * 修改专利作者
     * @param patentAuthor
     * @return
     */
    @Override
    public boolean updatePatentAuthor(Patentauthor patentAuthor) {
        Patent p = iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();
        checkRoleUtil.checkPermissionAchievement(p.getStatus());

        if (StrUtil.isEmpty(patentAuthor.getAssessment())) {
            throw new BaseException("请输入考核系数");
        }

        double newAssessment;
        try {
            String assessment = patentAuthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0-100范围内");
        }

        String Pscore = "0.00";
        Patent patent = iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();

        if(patent != null && patent.getScore() > 0){
            float finalValue = patent.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 先获取数据库中的原始记录
        Patentauthor originalAuthor = baseMapper.selectById(patentAuthor.getPatentAuthorID());
        if (originalAuthor == null) {
            throw new BaseException("未找到要修改的记录");
        }

        // 查询该专利的所有作者
        List<Patentauthor> patentauthorList = query().eq("PatentID", patentAuthor.getPatentID()).list();

        // 判断加起来总分是否超过100
        double sum = 0;
        // 只计算已填写考核系数的作者，并且排除当前正在更新的作者
        for (Patentauthor author : patentauthorList) {
            // 排除当前正在更新的记录，避免重复计算
            if (!author.getPatentAuthorID().equals(patentAuthor.getPatentAuthorID())) {
                if (!StrUtil.isBlank(author.getAssessment())) {
                    sum += Double.parseDouble(author.getAssessment());
                }
            }
        }

        // 检查已填写作者考核系数总和是否超过100
        if (sum + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100");
        }

        patentAuthor.setPscore(Pscore);
        boolean result = baseMapper.updateById(patentAuthor) == 1;

        // 维护AllInventor字段
        if (result) {
            updateAllInventor(p, patentAuthor);
        }

        return result;
    }


    /**
     * 查询专利的作者
     * @param id 专利ID
     * @return 专利作者列表
     */
    @Override
    public List<Patentauthor> listAuthor(String id) {
        List<Patentauthor> list = baseMapper.selectList(Wrappers.lambdaQuery(Patentauthor.class)
                .eq(Patentauthor::getPatentID, id));

        list.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        return list;
    }

    /**
     * 校级管理员修改作者
     *
     * @param patentAuthor
     * @return
     */
    @Override
    public boolean upPatentAuthor(Patentauthor patentAuthor) {
        Patent p = iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();
        checkRoleUtil.checkPermissionAchievement(p.getStatus());
        double newAssessment;
        try {
            String assessment = patentAuthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0-100范围内");
        }

        String Pscore = "0.00";

        Patent patent= iPatentService.query().eq("PatentID", patentAuthor.getPatentID()).one();

        if(patent != null){
            float finalValue = patent.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 查询该专利的所有作者
        List<Patentauthor> patentauthorList = query().eq("PatentID", patentAuthor.getPatentID()).list();
        // 判断加起来总分是否超过100
        double sum = 0;
        for (Patentauthor patentauthor : patentauthorList) {
            if(StrUtil.isEmpty(patentauthor.getAssessment())){
                throw new BaseException("请补全所有作者考核系数");
            }
            sum += Double.parseDouble(patentauthor.getAssessment());
            if (sum > 100) {
                throw new BaseException("该专利的作者总分和超过100");
            }
        }

        patentAuthor.setPscore(Pscore);
        boolean result = baseMapper.updateById(patentAuthor) == 1;

        // 维护AllInventor字段
        if (result) {
            updateAllInventor(p, patentAuthor);
        }

        return result;
    }


    /**
     * 维护AllInventor字段
     * @param patent
     * @param patentAuthor
     */
    private void updateAllInventor(Patent patent, Patentauthor patentAuthor) {
        // 1. 先删除原来的AllInventor字段
        patent.setAllAuthor(null);
        iPatentService.updateById(patent);

        // 2. 查询该专利的所有作者
        List<Patentauthor> allInventorList = iPatentauthorService.listAuthor(patentAuthor.getPatentID());
        // 3. 按照作者类型排序
        allInventorList.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        // 4. 根据工号集合查询用户的主键id
        List<String> userAccountList = allInventorList.stream()
                .map(Patentauthor::getUserAccount)
                .collect(Collectors.toList());
        List<User> userList = Collections.emptyList();
        if (!userAccountList.isEmpty()) {
            userList = iUserService.list(Wrappers.lambdaQuery(User.class)
                    .in(User::getAccount, userAccountList));
        }
        List<String> uidList = userList.stream()
                .map(User::getUid)
                .collect(Collectors.toList());
        // 5. 将主键id拼接成字符串
        String allInventor = String.join(",", uidList);
        // 6. 更新AllInventor字段
        patent.setAllAuthor(allInventor);
        iPatentService.updateById(patent);
    }
}
